package com.sztle.admodule;

import android.app.Activity;
import android.app.Application;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.bytedance.applog.AppLog;
import com.bytedance.applog.IDataObserver;
import com.bytedance.applog.IOaidObserver;
import com.bytedance.applog.InitConfig;
import com.bytedance.applog.alink.IALinkListener;
import com.bytedance.applog.util.UriConstants;
import com.bytedance.sdk.openadsdk.TTAdConfig;
import com.bytedance.sdk.openadsdk.TTAdManager;
import com.bytedance.sdk.openadsdk.TTAdSdk;
import com.bytedance.sdk.openadsdk.TTCustomController;
import com.bytedance.sdk.openadsdk.mediation.init.MediationPrivacyConfig;
import com.sztle.admodule.bean.AdConfigInfo;
import com.sztle.admodule.bean.RequestAdEntity;
import com.sztle.admodule.outstatus.AppStatusProcessor;
import com.sztle.admodule.someutils.Utils;
import com.sztle.admodule.control.manager.ControlManager;
import com.sztle.admodule.control.utils.UserDeviceUtils;
import com.sztle.admodule.myutils.AdLogUtils;

import org.json.JSONObject;

import java.util.LinkedList;
import java.util.Map;

public class GmAdManager {
    private static boolean isAdInit = false;
    private static boolean isInitEnd = false;
    private static boolean isInitSpark = false;
    private static boolean useAdExp = false;
    private static boolean localAdExp = true;
    private static boolean forbidSdkMode = !AppStatusProcessor.isDebug();

    private static IAdListener proxyReportLog;
    private static IAdjustListener adjustListener;
    private static LinkedList<RequestAdEntity> sRequestAdQueue = new LinkedList<>();

    public static void setForbidSdkMode(boolean flag) {
        GmAdManager.forbidSdkMode = flag;
        if(AppStatusProcessor.isDebug()){
            GmAdManager.forbidSdkMode = false;
        }

    }

    private static String getGroMoreId(){
        AdConfigInfo adConfigInfo = ControlManager.getAdConfigInfo();
        if(adConfigInfo != null && !TextUtils.isEmpty(adConfigInfo.groMoreId.trim())){
            return adConfigInfo.groMoreId;
        }
        return AppStatusProcessor.getAppParam().gremoreAppId;
    }

    private static String getAdSparkId(){
        AdConfigInfo adConfigInfo = ControlManager.getAdConfigInfo();
        if(adConfigInfo != null && !TextUtils.isEmpty(adConfigInfo.adsparkId.trim())){
            return adConfigInfo.adsparkId;
        }
        return AppStatusProcessor.getAppParam().adsparkAppId;
    }
    //请求
    public static void enterRequestAdQueue(RequestAdEntity entity) {
//        if (entity == null) {
//            return;
//        }
//        if (entity.requestLoadTime <= 0) {
//            entity.requestLoadTime = System.currentTimeMillis();
//        }
//        if (sRequestAdQueue.size() >= 50) {
//            //超过50个，把最老那个去除
//            sRequestAdQueue.pollLast();
//        }
//        sRequestAdQueue.offerFirst(entity);//从对头开始插入，队头最新
//        AdLogUtils.Log("AdjustProcess", "广告请求进队：" + entity.getAdName());
    }

    //10s 50次请求限制
    public static boolean isCanRequestAd() {
        if (sRequestAdQueue.size() < 50) {
            //少于50次请求
            return true;
        }
        //已经大于50次请求了
        long current = System.currentTimeMillis();
        RequestAdEntity oldestEntity = sRequestAdQueue.peekLast();//队尾最老,只看最老的就行了
        if (oldestEntity != null) {
            if (current - oldestEntity.requestLoadTime < 10 * 1000) {
                AdLogUtils.Log("AdjustProcess", "请求过于频繁，触发限制");
                return false;
            }
        }
        return true;
    }

    public static String lastMsg = "";



    public static void setAdjustListener(IAdjustListener adjustListener) {
        GmAdManager.adjustListener = adjustListener;
    }

    public static String getLastMsg() {
        if(lastMsg == null){
            return "";
        }
        return lastMsg;
    }

    public static void setUseAdExp(boolean useAdExp, String msg) {
        AdLogUtils.Log("AdjustProcess", "最终归因结果：" + msg + ":" + useAdExp);
        GmAdManager.useAdExp = useAdExp;
        if(AppStatusProcessor.isDebug()){
            GmAdManager.useAdExp = true;
        }

        lastMsg = msg;
        if (adjustListener != null) {
            adjustListener.adjustResult(msg, useAdExp);
        }
    }

    public static void forceCloseAd(){
        forbidSdkMode = false;
        GmAdManager.useAdExp = false;
    }


    public static boolean isUseAdExp() {
        if(UserDeviceUtils.isGMore()){
            return true;
        }
        if(forbidSdkMode){
            return false;
        }
        return useAdExp;
    }

    public static void setLocalAdExp(boolean localAdExp) {
        GmAdManager.localAdExp = localAdExp;
        if(AppStatusProcessor.isDebug()){
            GmAdManager.localAdExp = true;
        }
    }

    public static boolean isLocalAdExp() {
        if(UserDeviceUtils.isGMore()){
            return true;
        }
        if(forbidSdkMode){
            return false;
        }
        return localAdExp;
    }

    //adspark归因
    public static void initAdSpark(Activity activity, String channel, IAdSparkResult sparkResult) {
        if (activity == null) {
            return;
        }
        if (isInitSpark) {
            return;
        }
        /* 初始化开始，appid和渠道，appid如不清楚请联系对接人
         * 注意第二个参数 channel 填写渠道信息，不能为空
         */
        final InitConfig config = new InitConfig(getAdSparkId(), channel);
        //设置数据上送地址
        config.setUriConfig(UriConstants.DEFAULT);
        // 加密开关，SDK 5.5.1 及以上版本支持，false 为关闭加密，上线前建议设置为 true
        if (AppStatusProcessor.isDebug()) {
            AppLog.setEncryptAndCompress(false);
            //日志开关，debug阶段建议开启
            config.setLogEnable(true);
        } else {
            AppLog.setEncryptAndCompress(true);
            //日志开关，debug阶段建议开启
            config.setLogEnable(false);
        }

        AppLog.setALinkListener(new IALinkListener() {
            @Override
            public void onAttributionFailedCallback(Exception e) {
                AdLogUtils.Log("SelfAdManager", "onAttributionFailedCallback");
            }

            @Override
            public void onALinkData(@Nullable Map<String, String> map, @Nullable Exception e) {
                //空实现，不需要处理
                AdLogUtils.Log("SelfAdManager", "onALinkData");
            }

            @Override
            public void onAttributionData(@Nullable Map<String, String> map, @Nullable Exception e) {
                //空实现，不需要处理
                AdLogUtils.Log("SelfAdManager", "onAttributionData");
            }
        });
        /**
         * 用于获取用户唯一性bd_did
         * @description
         */
        AppLog.addDataObserver(new IDataObserver() {
            /**
             * 本地的id数据加载结果通知
             * @param did device id
             * @param iid install id
             * @param ssid ssid
             */
            @Override
            public void onIdLoaded(String did, String iid, String ssid) {
                String bd_did = AppLog.getDid();
                AdLogUtils.Log("SelfAdManager", "onIdLoaded = " + did);
                if (sparkResult != null && !TextUtils.isEmpty(did)) {
                    sparkResult.onDidResult(did);
                }
            }

            /**
             * 通知注册结果，以及id变化情况
             * 仅主进程会被调用
             * @param changed 是否和本地缓存有所不同
             * @param oldDid 原device id
             * @param newDid server返回新的device id
             * @param oldIid 原install id
             * @param newIid server返回新install id
             * @param oldSsid 原ssid
             * @param newSsid server返回新ssid
             */
            @Override
            public void onRemoteIdGet(boolean changed, String oldDid, String newDid, String oldIid, String newIid, String oldSsid, String newSsid) {
                String bd_did = AppLog.getDid();
                AdLogUtils.Log("SelfAdManager", "onRemoteIdGet = " + newDid);
                if (!TextUtils.isEmpty(newDid) && sparkResult != null) {
                    sparkResult.onDidResult(newDid);
                }
            }

            /**
             * Config拉取数据，和本地数据对比有变化的通知
             * 仅主进程会被调用
             * @param changed 是否和本地缓存有所不同
             * @param config server返回新config内容
             */
            @Override
            public void onRemoteConfigGet(boolean changed, JSONObject config) {

            }

            /**
             * server拉取AbConfig数据，和本地数据对比有变化的通知
             * 仅主进程会被调用
             * @param changed 是否和本地缓存有所不同
             * @param abConfig server返回新abConfig内容
             */
            @Override
            public void onRemoteAbConfigGet(boolean changed, JSONObject abConfig) {
                AdLogUtils.Log("---测试---返回全部进组信息", "" + abConfig.toString());
            }

            /**
             *  Vid变化通知
             */
            @Override
            public void onAbVidsChange(String s, String s1) {

            }

        });
        AppLog.setOaidObserver(new IOaidObserver() {
            @Override
            public void onOaidLoaded(@NonNull Oaid oaid) {
                if (oaid != null && !TextUtils.isEmpty(oaid.id) && sparkResult != null) {
                    sparkResult.onOaidResult(oaid.id);
                }
            }
        });
        // 是否 init 后自动 start 可改为 false，并请在用户授权后调用 AppLog.start()开始实际采集用户信息+上报
        config.setAutoStart(true);
        //全埋点开关，默认不开启
        config.setAutoTrackEnabled(false);
        /*
         * 针对联调管理功能更新SDK初始化配置，
         * 因此在集成SDK的时候必须开启延迟深度链接能力
         */
        config.enableDeferredALink();
        /*
         * 为确保合规，集成SDK后，会在获得用户授权之后进行SDK的初始化并开始采集信息，
         * 请确保您采集用户信息前已得到用户的授权
         * 补偿延迟对启动事件的数据影响，如不采用此方式初始化(init时使用三个参数的方法，第三
         * 个参数传当前activity)，会对设备ID获取率有较大影响，进而影响归因结果
         */
        AppLog.init(activity, config, activity);
        /**
         * 非常重要！！！会直接影响归因结果，必须设置
         * @description 而且建议在初始化后设置，否则可能不生效
         */
        AppLog.setHeaderInfo("csj_attribution", 1);
        isInitSpark = true;
    }

    private static boolean startInit = false;

    public static void checkInit(IAdListener adListener) {
        if (forbidSdkMode && !UserDeviceUtils.isGMore()) {
            return;
        }
        if (isAdSdkReady()) {
            if (adListener != null) {
                adListener.initComplete(true, true);
            }
            return;
        }

        if (startInit) {
            return;
        }
        startInit = true;
        init(Utils.getApp(), adListener);
    }

    public static void init(Application application, IAdListener iReportLog) {
        if (isAdInit && isAdSdkReady()) {
            if (iReportLog != null) {
                iReportLog.initComplete(true, true);
            }
            return;
        }
        proxyReportLog = iReportLog;
        TTAdSdk.init(application, buildConfig());
        TTAdSdk.start(new TTAdSdk.Callback() {
            @Override
            public void success() {
                isAdInit = true;
                isInitEnd = true;
                if (proxyReportLog != null) {
                    proxyReportLog.initComplete(false, isAdSdkReady());
                }

            }

            @Override
            public void fail(int i, String s) {
                isAdInit = false;
                isInitEnd = true;
                if (proxyReportLog != null) {
                    proxyReportLog.initComplete(false, isAdSdkReady());
                }
            }
        });
    }

    public static boolean isAdSdkReady() {
        return TTAdSdk.isSdkReady();
    }

    private static TTAdConfig buildConfig() {

        return new TTAdConfig.Builder()
                /**
                 * 注：需要替换成在媒体平台申请的appID ，切勿直接复制
                 */
                .appId(getGroMoreId())
                /**
                 * 上线前需要关闭debug开关，否则会影响性能
                 */
//                .debug(BuildConfig.DEBUG)
                /**
                 * 使用聚合功能此开关必须设置为true，默认为false
                 */
                .useMediation(true)
                .customController(getTTCustomController()) //如果您需要设置隐私策略请参考该api
//                .setMediationConfig(new MediationConfig.Builder() //可设置聚合特有参数详细设置请参考该api
//                        .setMediationConfigUserInfoForSegment(getUserInfoForSegment())//如果您需要配置流量分组信息请参考该api
//                        .build())
                .build();
    }


    //函数返回值表示隐私开关开启状态，未重写函数使用默认值
    private static TTCustomController getTTCustomController() {
        return new TTCustomController() {

            @Override
            public boolean isCanUseWifiState() {
                return false;
            }

            @Override
            public boolean isCanUsePhoneState() {
                return false;
            }

            @Override
            public String getMacAddress() {
                return super.getMacAddress();
            }

            @Override
            public boolean isCanUseWriteExternal() {
                return super.isCanUseWriteExternal();
            }

            @Override
            public String getDevOaid() {
                return super.getDevOaid();
            }

            @Override
            public boolean isCanUseAndroidId() {
                return super.isCanUseAndroidId();
            }

            @Override
            public String getAndroidId() {
                return super.getAndroidId();
            }

            @Override
            public MediationPrivacyConfig getMediationPrivacyConfig() {
                return new MediationPrivacyConfig() {

                    @Override
                    public boolean isLimitPersonalAds() {
                        return super.isLimitPersonalAds();
                    }

                    @Override
                    public boolean isProgrammaticRecommend() {
                        return super.isProgrammaticRecommend();
                    }
                };
            }

            @Override
            public boolean isCanUsePermissionRecordAudio() {
                return super.isCanUsePermissionRecordAudio();
            }
        };
    }

    public static TTAdManager get() {

        return TTAdSdk.getAdManager();
    }

    public static String getDid() {
        return AppLog.getDid();
    }

    //注册
    public static final String REGISTER = "grown_attribution_event_register";

    public static void appLogEvent(String event) {
        if (TextUtils.isEmpty(event)) {
            return;
        }
        AppLog.onEventV3(event);
    }

    //注册
    public static void appLogRegister() {
        appLogEvent(REGISTER);
    }

}
